import {Gradient} from "typescript-color-gradient"; // 颜色渐变


export interface IColorObj {
  r: number;
  g: number;
  b: number;
  a?: number;
}

export class ColorUtils {
  /**
   * 255颜色值转16进制颜色值
   * @param n 255颜色值
   * @returns hex 16进制颜色值
   */
  static toHex = (n: number) => `${n > 15 ? '' : 0}${n.toString(16)}`;

  /**
   * 颜色对象转化为16进制颜色字符串
   * @param colorObj 颜色对象
   */
  static toHexString = (colorObj: IColorObj) => {
    const {r, g, b, a = 1} = colorObj;
    return `#${ColorUtils.toHex(r)}${ColorUtils.toHex(g)}${ColorUtils.toHex(b)}${a === 1 ? '' : ColorUtils.toHex(Math.floor(a * 255))}`;
  };

  /**
   * 颜色对象转化为rgb颜色字符串
   * @param colorObj 颜色对象
   */
  static toRgbString = (colorObj: IColorObj) => {
    const {r, g, b} = colorObj;
    return `rgb(${r},${g},${b})`;
  };

  /**
   * 颜色对象转化为rgba颜色字符串
   * @param colorObj 颜色对象
   */
  static toRgbaString = (colorObj: IColorObj, n = 10000) => {
    const {r, g, b, a = 1} = colorObj;
    return `rgba(${r},${g},${b},${Math.floor(a * n) / n})`;
  };

  /**
   * 16进制颜色字符串解析为颜色对象
   * @param color 颜色字符串
   * @returns IColorObj
   */
  static parseHexColor = (color: string) => {
    let hex = color.slice(1);
    let a = 1;
    if (hex.length === 3) {
      hex = `${hex[0]}${hex[0]}${hex[1]}${hex[1]}${hex[2]}${hex[2]}`;
    }
    if (hex.length === 8) {
      a = parseInt(hex.slice(6), 16) / 255;
      hex = hex.slice(0, 6);
    }
    const bigint = parseInt(hex, 16);
    return {
      r: (bigint >> 16) & 255,
      g: (bigint >> 8) & 255,
      b: bigint & 255,
      a,
    } as IColorObj;
  };

  /**
   * rgba颜色字符串解析为颜色对象
   * @param color 颜色字符串
   * @returns IColorObj
   */
  static parseRgbaColor = (color: string) => {
    const arr = color.match(/(\d(\.\d+)?)+/g) || [];
    const res = arr.map((s: string) => parseInt(s, 10));
    let a = parseFloat(arr[3]);
    if (isNaN(a)) {
      a = 1
    }
    return {
      r: res[0],
      g: res[1],
      b: res[2],
      a: a,
    } as IColorObj;
  };

  /**
   * 颜色字符串解析为颜色对象
   * @param color 颜色字符串
   * @returns IColorObj
   */
  static parseColorString = (color: string) => {
    if (color.startsWith('#')) {
      return ColorUtils.parseHexColor(color);
    } else if (color.startsWith('rgb')) {
      return ColorUtils.parseRgbaColor(color);
    } else if (color === 'transparent') {
      return ColorUtils.parseHexColor('#00000000');
    }
    throw new Error(`color string error: ${color}`);
  };

  /**
   * 颜色字符串解析为各种颜色表达方式
   * @param color 颜色字符串
   * @returns IColorObj
   */
  static getColorInfo = (color: string) => {
    const colorObj = ColorUtils.parseColorString(color);
    const hex = ColorUtils.toHexString(colorObj);
    const rgba = ColorUtils.toRgbaString(colorObj);
    const rgb = ColorUtils.toRgbString(colorObj);
    return {
      hex,
      rgba,
      rgb,
      rgbaObj: colorObj,
    };
  };

  /**
   * 16进制颜色字符串转化为rgba颜色字符串
   * @param hex 16进制颜色字符串
   * @returns rgba颜色字符串
   */
  static hexToRgba = (hex: string) => {
    const colorObj = ColorUtils.parseColorString(hex);
    return ColorUtils.toRgbaString(colorObj);
  };

  /**
   * rgba颜色字符串转化为16进制颜色字符串
   * @param rgba rgba颜色字符串
   * @returns 16进制颜色字符串
   */
  static rgbaToHex = (rgba: string) => {
    const colorObj = ColorUtils.parseColorString(rgba);
    return ColorUtils.toHexString(colorObj);
  };


  /**
   * rbga其中一个进行混入
   * @param c1
   * @param c2
   * @param ratio 混合率 0-1
   */
  static rgbaOneMix(c1: number, c2: number, ratio: number): number {
    return Math.round(c1 * (1 - ratio) + c2 * ratio)
  }

  /**
   * 颜色混合：
   * @param c1
   * @param c2
   * @param ratio 混合率 0-1
   */
  static colourBlend = (c1: string, c2: string, ratio: number): string => {
    ratio = Math.max(Math.min(Number(ratio), 1), 0)
    let iColorObj1 = ColorUtils.parseColorString(c1);
    let iColorObj2 = ColorUtils.parseColorString(c2);
    let result: IColorObj = {
      r: ColorUtils.rgbaOneMix(iColorObj1.r, iColorObj2.r, ratio),
      g: ColorUtils.rgbaOneMix(iColorObj1.g, iColorObj2.g, ratio),
      b: ColorUtils.rgbaOneMix(iColorObj1.b, iColorObj2.b, ratio),
      a: ColorUtils.rgbaOneMix(iColorObj1.a, iColorObj2.a, ratio),
    }
    return ColorUtils.toRgbaString(result)
  };

  static getGradient(...gradients: string[]): Gradient {
    gradients = gradients.map(i => {
      let iColorObj = ColorUtils.parseColorString(i);
      console.log(i, iColorObj)
      return ColorUtils.toHexString(iColorObj)
    })
    console.log(gradients);
    return new Gradient()
      .setGradient(...gradients)
  }
}

/**
 hexToRgba('#a53eda') // rgba(165,62,218,1)
 rgbaToHex('rgba(165,62,218,1)') // #a53eda

 parseColorString('#a53eda') // {r: 165, g: 62, b: 218, a: 1}
 parseColorString('rgba(165,62,218,0.5)') // {r: 165, g: 62, b: 218, a: 0.5}

 toHexString({r: 165, g: 62, b: 218, a: 0.5}) // #a53eda7f
 toRgbaString({r: 165, g: 62, b: 218, a: 0.5}) // rgba(165,62,218,0.5)

 colourBlend('#ff0000', '#3333ff', 0.5) // "#991a80"
 */
